﻿//***************************************************************
// 类名：资源管理器初始化监视器
// 责任人：钟汶洁
// 修改日期：2015.7
// 功能：监视资源管理器的初始化
//***************************************************************

using UnityEngine;
#if UNITY_EDITOR	
using UnityEditor;
#endif
using System.Collections;
using System.Collections.Generic;

public class AssetBundleInitializeOperation : AssetBundleLoadOperation
{
    public enum AssetBundleInitializeProgress
    {
        /// <summary>
        /// 开始
        /// </summary>
        Start,
        /// <summary>
        /// 载入本地资源清单资源包
        /// </summary>
        DownloadLocalManifestAssetBundle,
        /// <summary>
        /// 载入本地资源清单文件
        /// </summary>
        LoadLocalManifestAsset,
        /// <summary>
        /// 载入远程资源清单资源包
        /// </summary>
        DownloadRemoteManifestAssetBundle,
        /// <summary>
        /// 载入远程资源清单文件
        /// </summary>
        LoadRemoteManifestAsset,
        /// <summary>
        /// 逐个下载资源包
        /// </summary>
        DownloadAssetBundles,
        /// <summary>
        /// 载入本地资源记录文件
        /// </summary>
        DownloadLocalAssetRecord,
        /// <summary>
        /// 载入远程资源记录文件
        /// </summary>
        DownloadRemoteAssetRecord,
        /// <summary>
        /// 完成
        /// </summary>
        Done,
        /// <summary>
        /// 失败
        /// </summary>
        Failed
    }

    protected bool m_IsOpenRemote; // 是否打开远程更新开关？
    protected string m_ManifestName; // 资源清单名
    protected string m_DownloadLocalManifestAssetBundleError; // 加载本地资源清单过程中产生的异常信息
    protected string m_DownloadRemoteManifestAssetBundleError; // 加载远程资源清单过程中产生的异常信息
    protected string m_DownloadRemoteAssetBundleError; // 加载远程资源包的过程中产生的异常信息
    protected string m_DownloadingAssetBundleName = ""; // 当前正在下载的资源包名
    protected AssetBundleRequest m_LocalManifestRequest = null; // 本地资源清单异步加载请求
    protected AssetBundleRequest m_RemoteManifestRequest = null; // 远程资源清单异步加载请求
    AssetBundleManifest m_LocalAssetBundleManifest = null; // 本地资源清单
    AssetBundleManifest m_RemoteAssetBundleManifest = null; // 远程资源清单
    List<string> m_NeedDownloadAssetBundles = new List<string>(); // 需要下载的资源包列表
    AssetBundleInitializeProgress m_Progress = AssetBundleInitializeProgress.Start; // 进度情况

    /// <summary>
    /// 当前初始化进展情况
    /// </summary>
    public AssetBundleInitializeProgress Progress
    {
        get { return m_Progress; }
    }

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="ManifestName">资源清单名</param>
    /// <param name="IsOpenRemote">是否打开热更新开关？</param>
    public AssetBundleInitializeOperation(string ManifestName, bool IsOpenRemote = false)
    {
        m_ManifestName = ManifestName;
        m_IsOpenRemote = IsOpenRemote;
    }
    /// <summary>
    /// 帧更新
    /// </summary>
    /// <returns>true：工作中，false：工作完毕</returns>
	public override bool Update()
    {
        switch (m_Progress)
        {
            case AssetBundleInitializeProgress.Start: // 开始           
#if UNITY_EDITOR
                if (AssetBundleManager.SimulateAssetBundleInEditor)
                {
                    // 编辑器中模拟资源模式下
                    AssetBundleManager.Instance().DownloadAssetRecord(true);
                    m_Progress = AssetBundleInitializeProgress.DownloadLocalAssetRecord;
                }
                else
#endif
                {
                    AssetBundleManager.Instance().LoadAssetBundleManifest(true);
                    m_Progress = AssetBundleInitializeProgress.DownloadLocalManifestAssetBundle;
                }
                return true;
            case AssetBundleInitializeProgress.DownloadLocalManifestAssetBundle: // 加载本地资源清单所在资源包
                {
                    LoadedAssetBundle bundle = AssetBundleManager.Instance().GetLoadedAssetBundle(m_ManifestName, out m_DownloadLocalManifestAssetBundleError);
                    if (bundle != null)
                    {
                        m_LocalManifestRequest = bundle.m_AssetBundle.LoadAssetAsync("AssetBundleManifest", typeof(AssetBundleManifest));
                        m_Progress = AssetBundleInitializeProgress.LoadLocalManifestAsset;
                        return true;
                    }
                    else
                    {
                        if (string.IsNullOrEmpty(m_DownloadLocalManifestAssetBundleError))
                        {
                            return true;
                        }
                        else
                        {
                            m_Progress = AssetBundleInitializeProgress.Failed;
                            return false;
                        }
                    }
                }
            case AssetBundleInitializeProgress.LoadLocalManifestAsset: // 加载本地资源清单
                if (m_LocalManifestRequest == null)
                {
                    m_Progress = AssetBundleInitializeProgress.Failed;
                    return false;
                }
                else
                {
                    if (m_LocalManifestRequest.isDone)
                    {
                        m_LocalAssetBundleManifest = m_LocalManifestRequest.asset as AssetBundleManifest;
                        AssetBundleManager.Instance().OnLocalAssetBundleManifestDownloaded(m_LocalAssetBundleManifest);
                        if (m_IsOpenRemote)
                        {
                            AssetBundleManager.Instance().UnloadAssetBundleManifest();
                            AssetBundleManager.Instance().LoadAssetBundleManifest(false);
                            m_Progress = AssetBundleInitializeProgress.DownloadRemoteManifestAssetBundle;
                        }
                        else
                        {
                            AssetBundleManager.Instance().DownloadAssetRecord(true);
                            m_Progress = AssetBundleInitializeProgress.DownloadLocalAssetRecord;
                        }
                    }
                    return true;
                }
            case AssetBundleInitializeProgress.DownloadRemoteManifestAssetBundle: // 下载远程资源清单所在资源包
                {
                    LoadedAssetBundle bundle = AssetBundleManager.Instance().GetLoadedAssetBundle(m_ManifestName, out m_DownloadRemoteManifestAssetBundleError);
                    if (bundle != null)
                    {
                        m_RemoteManifestRequest = bundle.m_AssetBundle.LoadAssetAsync("AssetBundleManifest", typeof(AssetBundleManifest));
                        m_Progress = AssetBundleInitializeProgress.LoadRemoteManifestAsset;
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(m_DownloadRemoteManifestAssetBundleError))
                        {
                            AssetBundleManager.Instance().OnLocalAssetBundleManifestDownloaded(m_LocalAssetBundleManifest);
                            AssetBundleManager.Instance().DownloadAssetRecord(true);
                            m_Progress = AssetBundleInitializeProgress.DownloadLocalAssetRecord;
                        }
                    }
                }
                return true;
            case AssetBundleInitializeProgress.LoadRemoteManifestAsset:
                if (m_RemoteManifestRequest == null)
                {
                    AssetBundleManager.Instance().OnLocalAssetBundleManifestDownloaded(m_LocalAssetBundleManifest);
                    AssetBundleManager.Instance().DownloadAssetRecord(true);
                    m_Progress = AssetBundleInitializeProgress.DownloadLocalAssetRecord;
                }
                else
                {
                    if (m_RemoteManifestRequest.isDone)
                    {
                        m_RemoteAssetBundleManifest = m_RemoteManifestRequest.asset as AssetBundleManifest;
                        string[] assetBundleNameArray = m_RemoteAssetBundleManifest.GetAllAssetBundles();

                        for (int i = 0; i < assetBundleNameArray.Length; ++i)
                        {
                            AssetBundleInfo info = AssetBundleManager.Instance().GetAssetBundleInfo(assetBundleNameArray[i]);
                            if (info != null)
                            {
                                Hash128 hash1 = info.assetBundleHash;
                                Hash128 hash2 = m_RemoteAssetBundleManifest.GetAssetBundleHash(assetBundleNameArray[i]);
                                if (!hash1.Equals(hash2))
                                {
                                    m_NeedDownloadAssetBundles.Add(assetBundleNameArray[i]);
                                }
                            }
                            else
                            {
                                m_NeedDownloadAssetBundles.Add(assetBundleNameArray[i]);
                            }
                        }
                        AssetBundleManager.Instance().UnloadAssetBundleManifest();
                        AssetBundleManager.Instance().OnRemoteAssetBundleManifestDownloaded(m_RemoteAssetBundleManifest);
                        m_Progress = AssetBundleInitializeProgress.DownloadAssetBundles;
                    }
                }
                return true;
            case AssetBundleInitializeProgress.DownloadAssetBundles:
                if (string.IsNullOrEmpty(m_DownloadingAssetBundleName))
                {
                    if (m_NeedDownloadAssetBundles.Count == 0)
                    {
                        AssetBundleManager.Instance().DownloadAssetRecord(false);
                        m_Progress = AssetBundleInitializeProgress.DownloadRemoteAssetRecord;
                    }
                    else
                    {
                        m_DownloadingAssetBundleName = m_NeedDownloadAssetBundles[0];
                        m_NeedDownloadAssetBundles.RemoveAt(0);
                        AssetBundleManager.Instance().LoadAssetBundle(m_DownloadingAssetBundleName, false);
                    }
                }
                else
                {
                    LoadedAssetBundle bundle = AssetBundleManager.Instance().GetLoadedAssetBundle(m_DownloadingAssetBundleName, out m_DownloadRemoteAssetBundleError);
                    if (bundle == null)
                    {
                        if (!string.IsNullOrEmpty(m_DownloadRemoteAssetBundleError))
                        {
                            AssetBundleManager.Instance().OnLocalAssetBundleManifestDownloaded(m_LocalAssetBundleManifest);
                            AssetBundleManager.Instance().DownloadAssetRecord(true);
                            m_Progress = AssetBundleInitializeProgress.DownloadLocalAssetRecord;
                        }
                    }
                    else
                    {
                        AssetBundleManager.Instance().UnloadAssetBundle(m_DownloadingAssetBundleName);
                        m_DownloadingAssetBundleName = "";
                    }
                }
                return true;
            case AssetBundleInitializeProgress.DownloadRemoteAssetRecord: // 加载远程资源记录文件
                if (!AssetBundleManager.Instance().IsLoadingAssetRecord())
                {
                    if (AssetBundleManager.Instance().IsAssetRecordLoaded())
                    {
                        m_Progress = AssetBundleInitializeProgress.Done;
                    }
                    else
                    {
                        AssetBundleManager.Instance().OnLocalAssetBundleManifestDownloaded(m_LocalAssetBundleManifest);
                        AssetBundleManager.Instance().DownloadAssetRecord(true);
                        m_Progress = AssetBundleInitializeProgress.DownloadLocalAssetRecord;
                    }
                }
                return true;
            case AssetBundleInitializeProgress.DownloadLocalAssetRecord: // 加载本地资源记录文件
                if (!AssetBundleManager.Instance().IsLoadingAssetRecord())
                {
                    if (AssetBundleManager.Instance().IsAssetRecordLoaded())
                    {
                        m_Progress = AssetBundleInitializeProgress.Done;
                    }
                    else
                    {
                        m_Progress = AssetBundleInitializeProgress.Failed;
                    }
                }
                return true;
            case AssetBundleInitializeProgress.Done: // 初始化成功
                return false;
            default: // 初始化失败
                return false;
        }
    }

    /// <summary>
    /// 是否加载完毕
    /// </summary>
    /// <returns>true：完毕；false：未完毕</returns>
	public override bool IsDone()
    {
        if (m_Progress == AssetBundleInitializeProgress.Done || m_Progress == AssetBundleInitializeProgress.Failed)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}
